package cn.cellcom.agent.struts.action;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.cellcom.agent.biz.TChannelBiz;
import cn.cellcom.agent.biz.TCrmBiz;
import cn.cellcom.agent.biz.TExtendBiz;
import cn.cellcom.agent.biz.TGroupBiz;
import cn.cellcom.agent.biz.TLwBiz;
import cn.cellcom.agent.biz.TSessionBiz;
import cn.cellcom.agent.biz.TSettingBiz;
import cn.cellcom.agent.biz.TUserBiz;
import cn.cellcom.agent.common.AgentConstant;
import cn.cellcom.agent.entity.TSettingEntity;
import cn.cellcom.agent.online.client.AgentClient;
import cn.cellcom.agent.online.client.ClientManager;
import cn.cellcom.agent.online.client.IDManager;
import cn.cellcom.agent.online.iq.ProcessorResult;
import cn.cellcom.agent.online.iq.agent.AgentProcessors;
import cn.cellcom.agent.online.iq.agent.CountMessageProcessor;
import cn.cellcom.agent.online.iq.agent.CrmFieldProcessor;
import cn.cellcom.agent.online.iq.agent.CrmHistoryProcessor;
import cn.cellcom.agent.online.iq.agent.CrmInfoProcessor;
import cn.cellcom.agent.online.iq.agent.CrmLogProcessor;
import cn.cellcom.agent.online.iq.agent.GroupsAndMemberProcessor;
import cn.cellcom.agent.online.iq.agent.LwDetailProcessor;
import cn.cellcom.agent.online.iq.agent.ModifyCrmProcessor;
import cn.cellcom.agent.online.message.MessageConstant;
import cn.cellcom.agent.pojo.TCrm;
import cn.cellcom.agent.pojo.TUser;
import cn.cellcom.agent.struts.form.VisitorForm;
import cn.cellcom.jar.biz.AbstractBiz;
import cn.cellcom.jar.dao.IBaseDao;
import cn.cellcom.jar.logon.LogonSession;
import cn.cellcom.jar.util.CopyUtil;
import cn.cellcom.jar.util.LogUtil;
import cn.cellcom.jar.util.MyException;

/**
 * 访客端访问逻辑
 * 
 * @author 郑余杰
 */
public class AgentDpAct extends DispatchAction {

	private Logger log = LoggerFactory.getLogger(this.getClass());

	private TGroupBiz gbiz;

	private TSettingBiz sbiz;

	private TLwBiz lbiz;

	private TUserBiz ubiz;

	private IBaseDao dao;

	private TSessionBiz ssbiz = null;

	private TCrmBiz cbiz;

	private TChannelBiz chbiz;

	private TExtendBiz ebiz;

	/**
	 * 坐席登陆上线
	 * 
	 * @param mapping
	 * @param form
	 * @param req
	 * @param rep
	 * @return
	 */
	public ActionForward online(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse rep) {
		LogonSession ls = new LogonSession(req);
		TUser user = (TUser) ls.getLogonObject();
		if (user == null) {
			// 让登陆知道是从这里进去的，other为AGENT_LOGIN时登陆则跳转到坐席界面
			req.setAttribute("other", AgentConstant.AGENT_LOGIN);
			return mapping.findForward("logon");
		}
		log.info("[{}] <LOGON> from ip[{}]", user.getUsername(), req.getRemoteAddr());

		/*
		 * 产生在线记录并执行相关操作
		 */
		try {
			AgentClient agentClient = (AgentClient) ClientManager.getInstance().getClient(user.getUsername());
			if (agentClient == null) {
				agentClient = new AgentClient(ssbiz, gbiz, user, req.getSession().getId());
				ClientManager.getInstance().record(agentClient);
				log.info("[{}] have no client, so create it [{}]", user.getUsername(), agentClient);
			} else {
				agentClient.setAgent(user);
				log.info("[{}] have exist client[{}]", user.getUsername(), agentClient);
			}
			// 每次登陆重新拿去配置信息
			TSettingEntity setting = sbiz.getAgentSetting(user.getPid(), user.getUsername(), false);
			agentClient.setSetting(setting);
			agentClient.online();
			req.setAttribute("orgHeader", setting.getOrgHeader());
			// 以下参数为了支持体验实名访问
			String timestamp = String.valueOf(System.currentTimeMillis());
			req.setAttribute("trytimestamp", timestamp);
			req.setAttribute("trytoken", IDManager.getToken(user.getUsername(), timestamp, setting.getAccessKey()));
			/*
			 * List<TGroup> groups = ubiz.getGroups(user.getUsername());
			 * agentClient.joinGroup(groups);
			 */

			List extendList = ebiz.getExtendList(user.getPid(), AgentConstant.EXTEND.ONLINE);
			req.setAttribute("extendList", extendList);
		} catch (MyException e) {
			return LogUtil.e(this.clazz, "请求参数有误[20004]", e, mapping, req);
		}
		return mapping.findForward("agent");
	}

	/**
	 * 
	 * @param mapping
	 * @param form
	 * @param req
	 * @param rep
	 * @return
	 */
	public ActionForward processor(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse rep) {
		VisitorForm cf = (VisitorForm) form;
		LogonSession ls = new LogonSession(req);
		TUser user = (TUser) ls.getLogonObject();
		if (user == null) {
			Response.err(rep, "坐席已经退出，请关闭浏览器[3000]");
			return null;
		}
		AgentClient client = (AgentClient) ClientManager.getInstance().getClient(user.getUsername());
		if (client == null) {
			// 管理员可能没有登陆坐席，但是查询crm的聊天信息
			if (CrmLogProcessor.NAME.equals(cf.getEvent())) {
			} else {
				Response.err(rep, "请刷新浏览器访问[30001]");
				log.info("[{}] have no client", user.getUsername());
				return null;
			}
		} else {
			client.setLastActiveTime();
		}

		Map<String, AbstractBiz> bizs = new HashMap<String, AbstractBiz>();
		if (ModifyCrmProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("cbiz", cbiz);
			try {
				TCrm crm = new TCrm();
				CopyUtil.copy(req, crm, null, false);
				cf.setObject(crm);
			} catch (MyException e) {
			}
		} else if (GroupsAndMemberProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("gbiz", gbiz);
			bizs.put("ubiz", ubiz);
		} else if (CrmFieldProcessor.NAME.equals(cf.getEvent()) || CrmInfoProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("cbiz", cbiz);
		} else if (CrmHistoryProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("sbiz", ssbiz);
		} else if (MessageConstant.MESSAGE_EVENT.AG_CHANGE_MAXCHAT.name().equals(cf.getEvent())) {
			bizs.put("sbiz", sbiz);
		} else if ("talking".equals(cf.getEvent()) || "history".equals(cf.getEvent())) {
			bizs.put("sbiz", ssbiz);
			bizs.put("gbiz", gbiz);
		} else if ("lwNoHandled".equals(cf.getEvent()) || "lwHandled".equals(cf.getEvent()) || LwDetailProcessor.NAME.equals(cf.getEvent())) {
			bizs.put("lbiz", lbiz);
		} else if (CrmLogProcessor.NAME.equals(cf.getEvent()) && client == null) {
			client = new AgentClient(null, null, user, null);
		}
		ProcessorResult result = AgentProcessors.createProcessors().process(bizs, client, cf);
		if (result != null) {
			Object dt = result.getData();
			if (dt == null) {
				dt = "";
			}
			if (result.isSuccess()) {
				if (dt instanceof List) {
					Response.succ(rep, (List) result.getData());
				} else if (dt instanceof Collection) {
					Response.succ(rep, (Collection) result.getData());
				} else if (dt instanceof String) {
					Response.succ(rep, String.valueOf(result.getData()));
				} else {
					Response.succObject(rep, dt);
				}
			} else {
				Response.err(rep, String.valueOf(dt));
			}
			if (StringUtils.isNotBlank(cf.getEvent())) {
				if (cf.getEvent().equals(CountMessageProcessor.NAME)) {
					log.trace("[{}] <IQ_MESSAGE> get " + cf.getEvent() + "[{}]", client.getId(), dt);
				} else {
					log.info("[{}] <IQ_MESSAGE> get " + cf.getEvent() + "[{}]", client.getId(), dt);
				}
			}
			return null;
		} else {
			log.error("[{}] <IQ_MESSAGE> get fail for event[{}]", client.getId(), cf.getEvent());
		}
		return null;
	}

	public void setSbiz(TSettingBiz sbiz) {
		this.sbiz = sbiz;
	}

	public void setDao(IBaseDao dao) {
		this.dao = dao;
	}

	public void setUbiz(TUserBiz ubiz) {
		this.ubiz = ubiz;
	}

	public void setGbiz(TGroupBiz gbiz) {
		this.gbiz = gbiz;
	}

	public void setSsbiz(TSessionBiz ssbiz) {
		this.ssbiz = ssbiz;
	}

	public void setCbiz(TCrmBiz cbiz) {
		this.cbiz = cbiz;
	}

	public void setLbiz(TLwBiz lbiz) {
		this.lbiz = lbiz;
	}

	public void setEbiz(TExtendBiz ebiz) {
		this.ebiz = ebiz;
	}

	public void setChbiz(TChannelBiz chbiz) {
		this.chbiz = chbiz;
	}

}
